package com.dhcc.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.api.R;
import com.dhcc.request.PositionAddRequest;
import com.dhcc.entity.*;
import com.dhcc.httpApiService.IdGeneratorService;
import com.dhcc.request.PositionResourceAllocationRequest;
import com.dhcc.response.SysResourceListTree;
import com.dhcc.service.*;
import com.dhcc.support.Condition;
import com.dhcc.support.Query;
import com.dhcc.response.SysDeptListTree;
import com.dhcc.utils.AuthUtil;
import com.dhcc.utils.ResourceTreeBuilder;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 部门管理控制层接口
 * @ProjectName Dhcc-Cloud
 * @PackageName com.dhcc.controller
 * @Title SysDeptController
 * @Date 2024/12/25 20:15
 * @Author LiuGuoting
 */
@RestController
@RequestMapping("/sys/dept")
public class SysDeptController {

    /**
     * ID生成器接口
     */
    @Resource
    IdGeneratorService idGeneratorService;
    /**
     * 用户管理服务接口
     */
    @Resource
    private SysUserService sysUserService;
    /**
     * 部门管理服务接口
     */
    @Resource
    private SysDeptService sysDeptService;
    /**
     * 岗位管理服务接口
     */
    @Resource
    private SysPositionService sysPositionService;
    /**
     * 部门岗位关联服务接口
     */
    @Resource
    private SysDeptPositionService sysDeptPositionService;
    /**
     * 部门岗位资源关联服务接口
     */
    @Resource
    private SysDeptPositionResourceService sysDeptPositionResourceService;
    /**
     * 部门岗位用户关联服务接口
     */
    @Resource
    private SysDeptPositionUserService sysDeptPositionUserService;
    @Autowired
    private SysResourceService sysResourceService;


    /**
     * 分页列表查询
     *
     * @param sysDept 部门信息实体对象
     * @param query 查询参数
     * @return 分页查询结果
     */
    @GetMapping("/page")
    public R<IPage<SysDeptListTree>> page(SysDept sysDept, Query query) {
        IPage<SysDeptListTree> pages = sysDeptService.selectDeptPage(Condition.getPage(query), sysDept);
        return R.data(pages);
    }

    /**
     * 列表查询
     *
     * @return 部门列表
     */
    @GetMapping("/listTree")
    public R<List<SysDeptListTree>> listDeptAll() {
        return R.data(sysDeptService.listDeptTree());
    }

    /**
     * 新增部门
     *
     * @param sysDept 部门信息实体对象
     * @return 操作结果
     */
    @PostMapping("/add")
    public R<Boolean> add(@RequestBody SysDept sysDept) {
        return R.status(sysDeptService.addDept(sysDept), "新增部门成功");
    }

    /**
     * 查询部门详情
     *
     * @param deptId 部门ID
     * @return 部门详情
     */
    @GetMapping("/detail")
    public R<SysDept> detail(@RequestParam("deptId") String deptId) {
        return R.data(sysDeptService.getDeptById(deptId));
    }

    /**
     * 修改部门信息
     *
     * @param sysDept 部门信息实体对象
     * @return 操作结果
     */
    @PostMapping("/update")
    public R<Map<String, Object>> update(@RequestBody SysDept sysDept) {
        return R.status(sysDeptService.updateDept(sysDept), "修改部门成功");
    }

    /**
     * 删除部门
     *
     * @param params 部门ID
     * @return 操作结果
     */
    @PostMapping("/delete")
    public R<Boolean> deleteDetp(@RequestBody Map<String, String> params) {
        // 从Map中获取id值，并转换为Long类型
        String id = params.get("id");
        // 如果部门下还有未删除的子部门，则不允许删除
        boolean hasUndeletedChildDepartments = hasUndeletedChildDepartments(id);
        if (hasUndeletedChildDepartments) {
            return R.fail("该部门下还有未删除的子部门，请先删除子部门！");
        }
        List<SysDept> sysDepts = sysDeptService.list();
        if (sysDepts.size() == 1) {
            return R.fail("请至少保留一个部门！");
        }
        return R.status(sysDeptService.deleteByIdLogic(id), "删除部门成功");
    }

    /**
     * 批量删除部门
     * @param ids 部门ID列表
     * @return 操作结果
     */
    @PostMapping("/deleteBatch")
    public R<Boolean> deleteBatchDept(@RequestBody List<String> ids) {
        for (String id : ids) {
            boolean hasUndeletedChildDepartments = hasUndeletedChildDepartments(id);
            if (hasUndeletedChildDepartments) {
                return R.fail("部门id为" + id + "的部门下还有未删除的子部门，请先删除子部门！");
            }
        }
        List<SysDept> sysDepts = sysDeptService.list();
        if (sysDepts.size() == ids.size()) {
            return R.fail("请至少保留一个部门！");
        }
        return R.status(sysDeptService.deleteBatchByIdsLogic(ids), "批量删除部门成功");
    }

    /**
     * 更改部门状态
     *
     * @param sysDept 部门对象
     * @return 操作结果
     */
    @PostMapping("/updateStatus")
    public R<Boolean> updateStatus(@RequestBody SysDept sysDept) {
        return R.status(sysDeptService.changeDeptStatus(sysDept.getId(), sysDept.getStatus()), "更改部门状态成功");
    }

    /**
     * 批量更改部门状态
     *
     * @param ids 部门ID列表
     * @param newStatus 新状态
     * @return 操作结果
     */
    @PostMapping("/updateStatusBatch")
    public R<Boolean> updateStatusBatch(List<String> ids, int newStatus) {
        return R.status(sysDeptService.changeDeptStatuss(ids, newStatus), "批量更改部门状态成功");
    }

    /**
     * 岗位管理子页面-查询岗位列表
     *
     * @param deptId 部门ID
     * @return 部门详情
     */
    @GetMapping("/positionList")
    public R<List<SysPosition>> positionList(@RequestParam("deptId") String deptId) {
        // new一个空的SysDept对象列表，用于存放查询结果
        List<SysPosition> sysPositionList = new ArrayList<>();
        // 创建一个查询条件，用于查找与部门ID匹配的SysDeptPosition记录
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda().eq(SysDeptPosition::getDepartmentId, deptId);
        // 执行查询，查询出所有与部门ID匹配的SysDeptPosition记录
        List<SysDeptPosition> sysDeptPositionList = sysDeptPositionService.list(sysDeptPositionQueryWrapper);
        // 遍历SysDeptPosition记录，获取对应的SysDept记录，并添加到sysDeptList列表中
        for (SysDeptPosition sysDeptPosition : sysDeptPositionList) {
            // 获取SysDeptPosition记录中的positionId字段的值，并将其转换为Long类型
            Long positionId = sysDeptPosition.getPositionId();
            // 根据positionId字段的值，查询SysDept记录并获取结果
            SysPosition sysPosition = sysPositionService.getById(positionId);
            // 将SysDept记录添加到sysDeptList列表中
            sysPositionList.add(sysPosition);
        }
        // 返回查询结果
        return R.data(sysPositionList);
    }

    /**
     * 岗位管理子页面-添加岗位
     *
     * @param positionAddRequest 请求体封装类，包含部门ID和职位ID列表
     * @return 部门详情
     */
    @PostMapping("/positionAdd")
    public R<Boolean> positionAdd(@RequestBody PositionAddRequest positionAddRequest) {
        // 添加前先删除该部门下的所有岗位
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda().eq(SysDeptPosition::getDepartmentId, positionAddRequest.getDepartmentId());
        sysDeptPositionService.remove(sysDeptPositionQueryWrapper);
        // 获取请求体中的部门ID和职位ID列表
        String departmentId = positionAddRequest.getDepartmentId();
        // 遍历职位ID列表，创建SysDeptPosition对象，并保存到数据库
        List<String> positionIds = positionAddRequest.getPositionIds();
        // 创建一个空的SysDeptPosition对象列表，用于存放新增的部门岗位关联数据
        List<SysDeptPosition> sysDeptPositions = new ArrayList<>();
        // 遍历职位ID列表，创建SysDeptPosition对象，并添加到sysDeptPositions列表中
        for (String positionId : positionIds) {
            SysDeptPosition sysDeptPosition = new SysDeptPosition();
            sysDeptPosition.setId(idGeneratorService.nextId());
            sysDeptPosition.setDepartmentId(Long.valueOf(departmentId));
            sysDeptPosition.setPositionId(Long.valueOf(positionId));
            sysDeptPositions.add(sysDeptPosition);
        }
        // 批量保存部门岗位关联数据
        boolean save = sysDeptPositionService.saveOrUpdateBatch(sysDeptPositions);
        // 返回操作结果
        return R.status(save, "添加岗位失败！");
    }
    /**
     * 岗位管理子页面-删除岗位
     *
     * @param sysDeptPosition 部门岗位实体对象
     * @return 部门详情
     */
    @PostMapping("/positionDelete")
    public R<Boolean> positionDelete(@RequestBody SysDeptPosition sysDeptPosition) {
        String userId = AuthUtil.getUserId();
        if (userId == null) {
            return R.status(false, "删除失败，您的登录信息已失效，请重新登录！");
        }
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda()
                .eq(SysDeptPosition::getDepartmentId, sysDeptPosition.getDepartmentId())
                .eq(SysDeptPosition::getPositionId, sysDeptPosition.getPositionId());
        SysDeptPosition sysDeptPositionServiceOne = sysDeptPositionService.getOne(sysDeptPositionQueryWrapper);
        if (sysDeptPositionServiceOne == null) {
            return R.status(false, "该岗位不存在！");
        }
        // 判断自己是否在该部门下的该岗位中
        Long sysDeptPositionId = sysDeptPositionServiceOne.getId();
        LambdaQueryWrapper<SysDeptPositionUser> sysDeptPositionIdQueryWrapper = new LambdaQueryWrapper<>();
        sysDeptPositionIdQueryWrapper.eq(SysDeptPositionUser::getDepartmentPosition, sysDeptPositionId);
        List<SysDeptPositionUser> sysDeptPositionUsers = sysDeptPositionUserService.list(sysDeptPositionIdQueryWrapper);
        for (SysDeptPositionUser sysDeptPositionUser : sysDeptPositionUsers) {
            if (sysDeptPositionUser.getUserId().equals(Long.parseLong(userId))){
                return R.status(false, "您在当前岗位下，请先退出该岗位！");
            }
        }
        // 查询部门岗位关联数据的id
        Long sysDeptPositionServiceOneId = sysDeptPositionServiceOne.getId();
        // 删除该部门岗位关联id 对应的部门岗位人员关联的数据
        sysDeptPositionUserService.remove(new QueryWrapper<SysDeptPositionUser>().lambda().eq(SysDeptPositionUser::getDepartmentPosition, sysDeptPositionServiceOneId));
        // 删除该部门岗位关联id 对应的部门岗位资源关联的数据
        sysDeptPositionResourceService.remove(new QueryWrapper<SysDeptPositionResource>().lambda().eq(SysDeptPositionResource::getDepartmentPosition, sysDeptPositionServiceOneId));
        // 返回删除结果
        boolean remove = sysDeptPositionService.remove(sysDeptPositionQueryWrapper);
        return R.status(remove, "删除岗位失败！");
    }
    /**
     * 岗位管理子页面-分配资源
     *
     * @param positionResourceAllocationRequest 请求体封装类，包含部门id和资源id集合
     * @return 部门详情
     */
    @PostMapping("/positionResourceAllocation")
    public R<SysDept> positionResourceAllocation(@RequestBody PositionResourceAllocationRequest positionResourceAllocationRequest) {
        // 创建一个空的部门岗位资源关联对象列表
        List<SysDeptPositionResource> sysDeptPositionResources = new ArrayList<>();
        // 接收部门ID，资源id数组
        String deptId = positionResourceAllocationRequest.getDepartmentId();
        String positionId = positionResourceAllocationRequest.getPositionId();
        List<String> resourcesIds = positionResourceAllocationRequest.getResourcesIds();
        // 查询部门岗位关联数据的id
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda()
                .eq(SysDeptPosition::getDepartmentId, Long.valueOf(deptId))
                .eq(SysDeptPosition::getPositionId, Long.valueOf(positionId));
        // 查询部门岗位关联数据
        SysDeptPosition sysDeptPositionOne = sysDeptPositionService.getOne(sysDeptPositionQueryWrapper);
        // 判断部门岗位关联数据是否存在
        if (sysDeptPositionOne == null) {
            // 部门岗位关联数据不存在
            return R.status(false, "该岗位不存在");
        }
        // 查询部门岗位关联数据的id
        Long sysDeptPositionOneId = sysDeptPositionOne.getId();
        // 先删除该部门岗位关联id 对应的部门岗位资源关联的数据
        sysDeptPositionResourceService.remove(
                new QueryWrapper<SysDeptPositionResource>().lambda()
                        .eq(SysDeptPositionResource::getDepartmentPosition, sysDeptPositionOneId));
        // 遍历资源id数组
        for (String resourceId : resourcesIds) {
            // 封装部门岗位资源关联对象
            SysDeptPositionResource sysDeptPositionResource = new SysDeptPositionResource();
            sysDeptPositionResource.setId(idGeneratorService.nextId());
            sysDeptPositionResource.setDepartmentPosition(sysDeptPositionOneId);
            sysDeptPositionResource.setResourceId(Long.valueOf(resourceId));
            // 添加到空的部门岗位资源关联对象列表中
            sysDeptPositionResources.add(sysDeptPositionResource);
        }
        // 批量保存部门岗位资源关联数据
        boolean save = sysDeptPositionResourceService.saveOrUpdateBatch(sysDeptPositionResources);
        // 返回操作结果
        return R.status(save, "分配资源失败！");
    }
    /**
     * 岗位管理子页面-分配数据权限
     * @return 部门详情
     */
    @PostMapping("/positionDataAllocation")
    public R<SysDept> positionDataAllocation() {
        return R.data(null,"暂未开发！");
    }

    /**
     * 岗位管理子页面-查询岗位下人员列表
     *
     * @param departmentId 部门ID
     * @param positionId 岗位ID
     * @return 部门详情
     */
    @GetMapping("/positionListUser")
    public R<List<SysUser>> positionListUser(@RequestParam("departmentId") Long departmentId,
                                             @RequestParam("positionId") Long positionId) {
        // 创建一个空的SysUser对象列表，用于存放查询结果
        List<SysUser> sysUserList = new ArrayList<>();
        // 创建一个查询条件，用于查找与部门ID和岗位ID匹配的SysDeptPosition记录
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda()
                .eq(SysDeptPosition::getDepartmentId, departmentId)
                .eq(SysDeptPosition::getPositionId, positionId);
        // 执行查询，查询出所有与部门ID和岗位ID匹配的SysDeptPosition记录
        SysDeptPosition sysDeptPositionOne = sysDeptPositionService.getOne(sysDeptPositionQueryWrapper);
        // 获取查询结果中的部门岗位ID字段的值，并将其转换为Long类型
        Long sysDeptPositionOneId = sysDeptPositionOne.getId();
        // 创建一个查询条件，用于查找与部门岗位ID匹配的SysDeptPositionUser记录
        QueryWrapper<SysDeptPositionUser> sysDeptPositionUserQueryWrapper = new QueryWrapper<>();
        sysDeptPositionUserQueryWrapper.lambda()
                .eq(SysDeptPositionUser::getDepartmentPosition, sysDeptPositionOneId);
        // 执行查询，查询出所有与部门岗位ID匹配的SysDeptPositionUser记录
        List<SysDeptPositionUser> users = sysDeptPositionUserService.list(sysDeptPositionUserQueryWrapper);
        // 遍历SysDeptPositionUser记录，获取对应的SysUser记录，并添加到sysUserList列表中
        for (SysDeptPositionUser user : users) {
            Long userId = user.getUserId();
            // 根据SysDeptPositionUser记录中的用户ID，查询对应的SysUser记录,并且只查询未删除的用户
            SysUser sysUser = sysUserService.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, userId).eq(SysUser::getDelFlag, 0));
            sysUserList.add(sysUser);
        }
        return R.data(sysUserList);
    }

    /**
     * 获取部门岗位所拥有的资源树
     *
     * 根据传入的部门ID和岗位ID，查询并构建该岗位在指定部门下所拥有的资源树形结构。
     *
     * @param departmentId 部门ID，用于指定查询的部门
     * @param positionId   岗位ID，用于指定查询的岗位
     * @return R<List<SysResourceListTree>> 包含资源树形结构的响应对象
     */
    @GetMapping("/getResourceTreeWithDeptPosition")
    public R<List<SysResourceListTree>> getResourceTreeWithDeptPosition(@RequestParam("departmentId") Long departmentId,
                                                                        @RequestParam("positionId") Long positionId){
        // 获取指定部门下指定岗位所拥有的资源（菜单）列表
        Set<SysResource> sysResources = new HashSet<>();

        // 查询部门岗位关联数据的id
        QueryWrapper<SysDeptPosition> sysDeptPositionQueryWrapper = new QueryWrapper<>();
        sysDeptPositionQueryWrapper.lambda()
                // 设置查询条件：部门ID等于传入的departmentId
                .eq(SysDeptPosition::getDepartmentId, departmentId)
                // 设置查询条件：岗位ID等于传入的positionId
                .eq(SysDeptPosition::getPositionId, positionId);

        // 查询部门岗位关联数据
        SysDeptPosition sysDeptPositionOne = sysDeptPositionService.getOne(sysDeptPositionQueryWrapper);
        if (sysDeptPositionOne == null){
            // 如果查询结果为空，表示该岗位不存在
            return R.fail("该岗位不存在");
        }

        // 查询部门岗位关联数据的id
        Long sysDeptPositionOneId = sysDeptPositionOne.getId();
        QueryWrapper<SysDeptPositionResource> sysDeptPositionResourceQueryWrapper = new QueryWrapper<>();
        sysDeptPositionResourceQueryWrapper.lambda()
                // 设置查询条件：部门岗位关联ID等于查询得到的sysDeptPositionOneId
                .eq(SysDeptPositionResource::getDepartmentPosition, sysDeptPositionOneId);

        // 查询部门岗位资源关联数据
        List<SysDeptPositionResource> sysDeptPositionResourceList = sysDeptPositionResourceService.list(sysDeptPositionResourceQueryWrapper);

        // 遍历部门岗位资源关联数据列表
        for (SysDeptPositionResource sysDeptPositionResource : sysDeptPositionResourceList) {
            LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
            // 设置查询条件：资源ID等于部门岗位资源关联数据中的resourceId
            sysResourceLambdaQueryWrapper.eq(SysResource::getId, sysDeptPositionResource.getResourceId());
            // 设置查询条件：删除标志为0，表示未删除的资源
            sysResourceLambdaQueryWrapper.eq(SysResource::getDelFlag, "0");
            SysResource sysResource = sysResourceService.getOne(sysResourceLambdaQueryWrapper);
            if (sysResource != null){
                // 如果资源存在，则添加到资源集合中
                sysResources.add(sysResource);
            }
        }

        // 4.菜单路由列表构建为菜单树形结构并返回
        // 使用构造方法转换为 List
        List<SysResource> menuTreeList = new ArrayList<>(sysResources);

        // 构建菜单树形结构
        List<SysResourceListTree> menuTree = ResourceTreeBuilder.buildResourceTree(menuTreeList,null);

        // 返回包含资源树形结构的响应对象
        return R.data(menuTree);
    }


    /**
     * 判断是否存在未删除的子部门
     *
     * @param departmentId 部门ID，用于查询其子部门
     * @return 如果存在未删除的子部门，则返回true；否则返回false
     */
    public boolean hasUndeletedChildDepartments(String departmentId) {
        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件：父部门ID等于传入的部门ID（假设fatherDepartmentId为String类型）
        queryWrapper.eq(SysDept::getFatherDepartmentId, departmentId);
        // 添加查询条件：删除标志等于0，表示未删除
        queryWrapper.eq(SysDept::getDelFlag, 0);
        // 执行查询，获取未删除的子部门列表
        List<SysDept> sysDeptChildList = sysDeptService.list(queryWrapper);
        // 判断子部门列表是否为空
        return !sysDeptChildList.isEmpty();
    }



}